}
ret = assign_device(d, bus, devfn);
- gdprintk(XENLOG_INFO, "XEN_DOMCTL_assign_device: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ if ( ret )
+ gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: "
+ "assign device (%x:%x.%x) failed\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
put_domain(d);
}
break;
if ( !device_assigned(bus, devfn) )
break;
- ret = 0;
- deassign_device(d, bus, devfn);
- gdprintk(XENLOG_INFO, "XEN_DOMCTL_deassign_device: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ spin_lock(&pcidevs_lock);
+ ret = deassign_device(d, bus, devfn);
+ spin_unlock(&pcidevs_lock);
+ if ( ret )
+ gdprintk(XENLOG_ERR, "XEN_DOMCTL_deassign_device: "
+ "deassign device (%x:%x.%x) failed\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
put_domain(d);
}
break;
if ( !iommu_pv_enabled && !is_hvm_domain(d) )
{
ret = -ENOSYS;
- put_domain(d);
- break;
+ goto assign_device_out;
}
- ret = -EINVAL;
-
ret = assign_device(d, bus, devfn);
if ( ret )
gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: "
if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) )
{
gdprintk(XENLOG_ERR,
- "XEN_DOMCTL_deassign_device: get_domain_by_id() failed\n");
+ "XEN_DOMCTL_deassign_device: get_domain_by_id() failed\n");
break;
}
if ( !iommu_pv_enabled && !is_hvm_domain(d) )
{
ret = -ENOSYS;
- put_domain(d);
- break;
+ goto deassign_device_out;
}
- ret = 0;
spin_lock(&pcidevs_lock);
ret = deassign_device(d, bus, devfn);
spin_unlock(&pcidevs_lock);
- gdprintk(XENLOG_INFO, "XEN_DOMCTL_deassign_device: bdf = %x:%x.%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ if ( ret )
+ gdprintk(XENLOG_ERR, "XEN_DOMCTL_deassign_device: "
+ "deassign device (%x:%x.%x) failed\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
deassign_device_out:
put_domain(d);
ret = -EPERM;
if ( !IS_PRIV(current->domain) &&
!irq_access_permitted(current->domain, bind->machine_irq) )
- goto bind_out;
+ goto unbind_out;
if ( iommu_enabled )
{
}
if ( ret < 0 )
gdprintk(XENLOG_ERR, "pt_irq_destroy_bind failed!\n");
+
+ unbind_out:
rcu_unlock_domain(d);
}
break;
{
struct hvm_iommu *hd = domain_hvm_iommu(d);
struct pci_dev *pdev = NULL;
+ int ret = 0;
if ( !iommu_enabled || !hd->platform_ops )
return -EINVAL;
ASSERT(spin_is_locked(&pcidevs_lock));
pdev = pci_get_pdev(bus, devfn);
- if (!pdev)
+ if ( !pdev )
return -ENODEV;
- if (pdev->domain != d)
+ if ( pdev->domain != d )
{
gdprintk(XENLOG_ERR VTDPREFIX,
"IOMMU: deassign a device not owned\n");
return -EINVAL;
}
- hd->platform_ops->reassign_device(d, dom0, bus, devfn);
+ ret = hd->platform_ops->reassign_device(d, dom0, bus, devfn);
+ if ( ret )
+ {
+ gdprintk(XENLOG_ERR VTDPREFIX,
+ "Deassign device (%x:%x.%x) failed!\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ return ret;
+ }
if ( !has_arch_pdevs(d) && need_iommu(d) )
{
hd->platform_ops->teardown(d);
}
- return 0;
+ return ret;
}
int iommu_setup(void)
{
pci_cleanup_msi(pdev);
bus = pdev->bus; devfn = pdev->devfn;
- deassign_device(d, bus, devfn);
+ if ( deassign_device(d, bus, devfn) )
+ printk("domain %d: deassign device (%02x:%02x.%x) failed!\n",
+ d->domain_id, pdev->bus, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn));
}
spin_unlock(&pcidevs_lock);
}